﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.ServiceModel;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using LiSA_Server.Base.NHibernate;
using log4net;

namespace LiSA_WindowsService
{
    public partial class Service1 : ServiceBase
    {
        /// <summary>
        /// The log.
        /// </summary>
        private ILog log;

        private ServiceHost clientHost;

        private void SetupLogging()
        {
            var logDir = AppDomain.CurrentDomain.BaseDirectory + "Logs\\";
            if (!Directory.Exists(logDir))
            {
                Directory.CreateDirectory(logDir);
            }

            this.log = LogManager.GetLogger(typeof(Service1));
        }

        public Service1()
        {
            InitializeComponent();
            this.SetupLogging();
        }

        protected override void OnStart(string[] args)
        {
            this.InitializeAssemblies();
            Console.WriteLine();

            this.UpdateNHibernate();
            Console.WriteLine();

            Console.Write("-> Creating services... ");
            var clientServiceType = typeof(LiSA_Service);
            this.clientHost = new ServiceHost(clientServiceType);
            this.clientHost.Open();

            Console.Write("\tDONE");
            Console.WriteLine();

            this.PrintServiceAddresses();
        }

        protected override void OnStop()
        {
            if (this.clientHost != null)
            {
                this.clientHost.Close();
            }
        }
        private void UpdateNHibernate()
        {
            this.log.Warn("Started: Updating NHibernate.");
            Console.Write("-> Updating NHibernate... ");
            NHibernateProvider.Instance.UpdateDb();
            Console.Write("\tDONE");
            Console.WriteLine();
            this.log.Warn("Finished: Updating NHibernate.");
        }
        private void PrintServiceAddresses(string hostName, ServiceHost host)
        {
            var logString = new StringBuilder();
            this.NewLines(2);
            Console.WriteLine("{0} hosted at: ", hostName);
            logString.Append(string.Format("{0} hosted at: ", hostName));
            foreach (var address in host.BaseAddresses)
            {
                Console.WriteLine("\t {0}", address.AbsoluteUri);
                logString.Append(string.Format("\t {0}", address.AbsoluteUri));
            }

            this.NewLines(2);
            this.log.Warn(logString);
        }

        private void NewLines(int i)
        {
            for (var j = 0; j < i; j++)
            {
                Console.WriteLine();
            }
        }

        public void PrintServiceAddresses()
        {
            if (this.clientHost != null)
            {
                this.PrintServiceAddresses("WpfClientService", this.clientHost);
            }
        }

        public void InitializeAssemblies()
        {
            this.log.Warn("Started: Initializing assemblies.");
            this.NewLines(2);
            Console.Write("-> Initializing assemblies... ");
            var assemblies = new List<Assembly>();
            foreach (var dll in Directory.GetFiles(this.AssemblyDirectory, "CalWin.*.dll", SearchOption.AllDirectories))
            {
                assemblies.Add(Assembly.LoadFrom(dll));
            }

            Console.Write("\tDONE");
            this.NewLines(2);
            this.log.Warn("Finished: Initializing assemblies.");
        }

        private string AssemblyDirectory
        {
            get
            {
                var path = this.GetAssemblyPath(Assembly.GetExecutingAssembly());
                return Path.GetDirectoryName(path);
            }
        }

        private string GetAssemblyPath(Assembly ass)
        {
            var codeBase = ass.CodeBase;
            var uri = new UriBuilder(codeBase);
            var path = Uri.UnescapeDataString(uri.Path);

            return path;
        }
    }
}
